/***************************************************************************
 *   oboe.resources.Files                                                  *
 *   Copyright (C) 2011 by Felipe Manga                                    *
 *   lufeboma@gmail.com                                                    *
 *                                                                         *
 *   Permission is hereby granted, free of charge, to any person obtaining *
 *   a copy of this software and associated documentation files (the       *
 *   "Software"), to deal in the Software without restriction, including   *
 *   without limitation the rights to use, copy, modify, merge, publish,   *
 *   distribute, sublicense, and/or sell copies of the Software, and to    *
 *   permit persons to whom the Software is furnished to do so, subject to *
 *   the following conditions:                                             *
 *                                                                         *
 *   The above copyright notice and this permission notice shall be        *
 *   included in all copies or substantial portions of the Software.       *
 *                                                                         *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       *
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    *
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR     *
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
 *   OTHER DEALINGS IN THE SOFTWARE.                                       *
 ***************************************************************************/

// In case of the following error, use this link.
// Error #2044: SecurityErrorEvent: não manipulado. text=Error #2140: Violação da área de segurança: [...]
// http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html

package oboe.resources 
{
	import flash.system.ApplicationDomain;
	import flash.utils.Dictionary;
	import flash.utils.setTimeout;
	
	import oboe.core.Oboe;
	import oboe.core.SigSlot;
	
	public class Files{
		
		private static var _instance : Files;
		
		// stores all the files indexed by their handles
		private static var _fileIndex : Dictionary = new Dictionary();
		
		public function Files() {
			FileRef.onLoadCallback = onLoad;
		}
		
		private static function get instance() : Files {
			if( !_instance ) _instance = new Files();
			return _instance;
		} 
		
		public static function registerResource( path : String, obj : Object, appDomain:ApplicationDomain ) : void {
			var ref : FileRef = new FileRef(path, "");
			_fileIndex[ ref.handle ] = ref;
			ref.appDomain = appDomain;
			ref.object = obj;
		}
	
		public static function getFile( handle : String ) : Object {
			if( handle == null || !(handle in _fileIndex) ) return null;
			return _fileIndex[handle].object; 
		}
		
		public static function getClass( handle : String, className : String ) : Class {
			var ref:Object = (_fileIndex[handle] as FileRef);
			if( !ref ) return null;
			return ref.appDomain.getDefinition(className) as Class;
		}
		
		public static function getInstance( handle : String, className : String ) : Object {
			var C : Class = getClass(handle, className );
			if( !C ) return null;
			return new C();
		}
		
		public static function getStaticInstance( handle : String, className : String ) : Object {
			var ref : FileRef = _fileIndex[handle] as FileRef;
			var inst : Object;
			if( ref.staticInstance == null ) ref.staticInstance = new Dictionary( true );
			inst = ref.staticInstance[className];
			if( inst == null ){
				var C : Class = ref.appDomain.getDefinition(className) as Class;
				inst = ref.staticInstance[className] = new C();
			}
			return inst;
		}
		
		private var totalLoaders : int = 0;
		private var pendingLoaders : int = 0;
		private var onCompleteCB : Function;
		private var progressListener : SigSlot;
		public static function loadList( load : Array, cb : Function, progressListener:SigSlot=null ) : void {
			if( !load || !load.length )
			{
				cb();
				return;
			}
			
			load = load.concat();

			instance.progressListener = progressListener;
			_instance.totalLoaders = instance.pendingLoaders = load.length;
			_instance.onCompleteCB = cb;
			for( var key:String in load )
			{
				var val:Object = load[key];
				var ref:FileRef = new FileRef(val);
				load[key] = ref;
				_fileIndex[ ref.handle ] = ref;
				if( Oboe.flags["SLOW_LOAD"] )
				{
					setTimeout( ref.load, 100 + Math.random()*1000 );
				}	
				else
				{
					ref.load();
				}
			}
		}
		
		private function onLoad() : void
		{
			this.pendingLoaders--;
			if( this.progressListener )
			{
				this.progressListener.message( "onProgress", 1 - this.pendingLoaders / this.totalLoaders );
			}
			if( !this.pendingLoaders && this.onCompleteCB != null )
			{
				this.onCompleteCB();
			}
		}
		
	}
}

